package com.cloudinnov.logic.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cloudinnov.dao.EquipmentsAttrDao;
import com.cloudinnov.dao.EquipmentsDao;
import com.cloudinnov.dao.ScreenDao;
import com.cloudinnov.logic.CameraControlLogic;
import com.cloudinnov.model.CameraModel;
import com.cloudinnov.model.Equipments;
import com.cloudinnov.model.EquipmentsAttr;
import com.cloudinnov.model.HikCameraData;
import com.cloudinnov.model.Screen;
import com.cloudinnov.utils.CodeUtil;
import com.cloudinnov.utils.CommonUtils;
import com.cloudinnov.utils.HttpUtil;
import com.cloudinnov.utils.JudgeNullUtil;
import com.cloudinnov.utils.PostgreSqlDbUtil;
import com.cloudinnov.utils.TcpClientUtil;

@Service("CameraControlLogic")
public class CameraControlLogicImpl extends BaseLogicImpl<Screen> implements CameraControlLogic {
	public static final Logger LOG = LoggerFactory.getLogger(CameraControlLogicImpl.class);
	private final static String CAMERA_NAME = "name";
	private final static String CAMERA_ID = "camera_id";
	private final static String NETWORK_ADDR = "network_addr";
	private final static String NETWORK_PORT = "network_port";
	private final static String CONTROL_NAME = "controlname";
	private final static String MATRIX_CODE = "matrix_code";
	private final static String INDEX_CODE = "index_code";
	private final static String DEVICE_ID = "device_id";
	/**
	 * @Fields CAMERA_TYPE :摄像机类型：0-枪机；1-半球；2-快球；3-云台
	 */
	private final static String CAMERA_TYPE = "camera_type";
	private final static int CAMERA_TYPE_QJ = 0;
	private final static int CAMERA_TYPE_BQ = 1;
	private final static int CAMERA_TYPE_KQ = 2;
	@Autowired
	private ScreenDao screenDao;
	@Autowired
	private EquipmentsAttrDao equipmentsAttrDao;
	@Autowired
	private EquipmentsDao equipmentsDao;

	@Override
	public int updateSwitchCamera(Screen screen) {
		return screenDao.updateByCondition(screen);
	}
	@Override
	public List<Screen> selectScreen(Screen screen) {
		return screenDao.selectListByCondition(screen);
	}
	@Override
	public int cameraStatus(CameraModel cameraModel) {
		boolean isConnect = false;
		// return TcpClientUtil.controllerCamera(CameraModel.CAMERA_GETSTATUS_CODE, DeviceId);
		try {
			isConnect = TcpClientUtil.ping(cameraModel.getIp());
		} catch (Exception e) {
			LOG.error("cameraStatus Is Bad,error: ", e);
		}
		if (!isConnect) {
			return 1004;
		}
		return 1;
	}
	@Override
	public int controllerCamera(CameraModel cameraModel) {
		return TcpClientUtil.controllerCamera(CameraModel.CAMERA_CONTROL_CODE,
				cameraModel.getCameraId() + CommonUtils.SPLIT_SEMICOLON + cameraModel.getControlCommand()
						+ CommonUtils.SPLIT_SEMICOLON + cameraModel.getAction());
	}
	@Override
	public String switchCamera(CameraModel cameraModel) {
		return HttpUtil.switchCamera(cameraModel.getIndexCode(), cameraModel.getScreenId());
	}
	@Override
	public void saveAllScreensByTwallCode(String twCode) {
		String result = HttpUtil.selectAllScreens(null);
		if (CommonUtils.isNotEmpty(result)) {
			int deleteCount = screenDao.deleteAll();
			LOG.debug("Delete Screens Is Success,Count Is " + deleteCount);
			Screen screen = null;
			JSONObject resultJson = JSON.parseObject(result);
			JSONArray tvwallList = resultJson.getJSONArray("tvwall_list");
			List<String> tvwallListString = JSON.parseArray(tvwallList.toJSONString(), String.class);
			if (tvwallList != null && tvwallList.size() > 0) {
				for (String tvwall : tvwallListString) {
					JSONObject tvwallModel = JSON.parseObject(tvwall);
					JSONArray dlpList = tvwallModel.getJSONArray("dlp_list");
					List<String> dlpListString = JSON.parseArray(dlpList.toJSONString(), String.class);
					if (dlpListString != null && dlpListString.size() > 0) {
						for (String dlp : dlpListString) {
							JSONObject dlpModel = JSON.parseObject(dlp);
							JSONArray floatwmdList = dlpModel.getJSONArray("floatwmd_list");
							List<String> floatwmdListString = JSON.parseArray(floatwmdList.toJSONString(),
									String.class);
							if (floatwmdListString != null && floatwmdListString.size() > 0) {
								for (String floatwmd : floatwmdListString) {
									JSONObject floatwmdModel = JSON.parseObject(floatwmd);
									JSONArray wndList = floatwmdModel.getJSONArray("wnd_list");
									List<String> wndListString = JSON.parseArray(wndList.toJSONString(), String.class);
									if (wndListString != null && wndListString.size() > 0) {
										for (String wnd : wndListString) {
											JSONObject wndModel = JSON.parseObject(wnd);
											screen = new Screen();
											screen.setCode(CodeUtil.screenCode(4));
											screen.setIndex(wndModel.getIntValue("wnd_id"));
											if (wndModel.getJSONObject("camera") == null) {
												continue;
											}
											screen.setName(wndModel.getJSONObject("camera").getString("name"));
											screen.setStatus(0);// 默认此屏幕未被任何摄像头投屏
											screenDao.insert(screen);
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	@Override
	public List<HikCameraData> saveAllHikCamera(HikCameraData model) {
		String sql = "SELECT camera.camera_id, camera.index_code, camera.name, camera.matrix_code, camera.camera_type, "
				+ "  device.device_id, device.network_addr, device.network_port, control.name AS controlname "
				+ "  FROM camera_info camera JOIN device_info device ON device.device_id = camera.device_id "
				+ "  JOIN control_unit control ON control.control_unit_id = camera.control_unit_id "
				+ "  WHERE device.status = 0";
		PostgreSqlDbUtil jdbcUtils = new PostgreSqlDbUtil();
		jdbcUtils.getConnection();
		List<Map<String, Object>> list = null;
		try {
			list = jdbcUtils.findModeResult(sql, null);
		} catch (SQLException e1) {
			LOG.error("get hikServerCameraData is error,e: {},  sql : {}", e1, sql);
		} finally {
			jdbcUtils.releaseConn();
			jdbcUtils = null;
		}
		if (JudgeNullUtil.iList(list)) {
			List<EquipmentsAttr> configList = equipmentsAttrDao.selectCameraListByCustomTag(CameraModel.IP);// 查询所有有ip的摄像头
			Equipments equipment = null;
			List<EquipmentsAttr> configsInsert = new ArrayList<>();
			List<EquipmentsAttr> configsUpdate = new ArrayList<>();
			List<Equipments> equipmentsInsert = new ArrayList<>();
			List<Equipments> equipmentsUpdate = new ArrayList<>();
			for (Map<String, Object> map : list) {// 遍历从海康查询的摄像头列表
				String ip = map.get(NETWORK_ADDR) != null ? (String) map.get(NETWORK_ADDR) : "";
				if (CommonUtils.isNotEmpty(ip)) {
					equipment = new Equipments();
					equipment.setLanguage("cn");
					equipment.setName((map.get(CONTROL_NAME) != null ? (String) map.get(CONTROL_NAME) : "") + "-"
							+ (map.get(CAMERA_NAME) != null ? (String) map.get(CAMERA_NAME) : ""));// 路段和摄像头的名称组成名称
					equipment.setPileNo(map.get(CAMERA_NAME) != null ? (String) map.get(CAMERA_NAME) : "");// 桩号
					int type = map.get(CAMERA_TYPE) != null
							? Integer.parseInt(String.valueOf(map.get(CAMERA_TYPE)).toString()) : 1;
					String cateCode = null;
					if (type == CAMERA_TYPE_QJ) {
						cateCode = "QSSXT";
					} else if (type == CAMERA_TYPE_BQ || type == CAMERA_TYPE_KQ) {
						cateCode = "QXSXT";
					}
					equipment.setCategoryCode(cateCode);
					boolean isUpdate = false;
					for (EquipmentsAttr config : configList) {// 遍历现有设备列表进行ip对比
						if (ip.equals(config.getValue())) {// 如果海康返回的ip和本系统的ip相同则进行设备更新和设备附加属性表更新
							equipment.setCode(config.getEquipmentCode());
							equipmentsUpdate.add(equipment);
							isUpdate = true;
							break;
						}
					}
					if (!isUpdate) {// 不同则进行设备更新和设备附加属性表添加设备附加属性表
						equipment.setCode(CodeUtil.equipmentCode(5));
						equipment.setStatus(CommonUtils.STATUS_NORMAL);
						equipment.setCreateTime(System.currentTimeMillis() + "");
						equipmentsInsert.add(equipment);
					}
					EquipmentsAttr equipmentAttr = null;
					for (Map.Entry<String, Object> entry : map.entrySet()) {
						if (entry.getKey().equals(NETWORK_ADDR) || entry.getKey().equals(NETWORK_PORT)
								|| entry.getKey().equals(INDEX_CODE) || entry.getKey().equals(CAMERA_ID)
								|| entry.getKey().equals(DEVICE_ID) || entry.getKey().equals(MATRIX_CODE)) {
							equipmentAttr = new EquipmentsAttr();
							equipmentAttr.setEquipmentCode(equipment.getCode());
							equipmentAttr.setCustomTag(entry.getKey());
							equipmentAttr.setValue(String.valueOf(entry.getValue()));
							equipmentAttr.setStatus(SUCCESS_NUM);
							getCustomTagByHikData(equipmentAttr);
							if (!isUpdate) {// 标识此设备为新设备,则设备附加表也插入数据
								configsInsert.add(equipmentAttr);
							} else {// 已存在此设备,则设备附加表更新数据
								configsUpdate.add(equipmentAttr);
							}
						}
					}
				}
			}
			Map<String, Object> params = new HashMap<>();
			if (JudgeNullUtil.iList(equipmentsInsert)) {// 批量添加设备
				params.put("list", equipmentsInsert);
				equipmentsDao.insertBatch(params);
			}
			if (JudgeNullUtil.iList(equipmentsUpdate)) {// 批量更新设备
				params.put("list", equipmentsUpdate);
				equipmentsDao.updateBatchByCondition(params);
			}
			if (JudgeNullUtil.iList(configsInsert)) {// 批量添加设备附加属性
				params.put("list", configsInsert);
				equipmentsAttrDao.insertBatch(params);
			}
			if (JudgeNullUtil.iList(configsUpdate)) {// 批量修改设备附加属性
				params.put("list", configsUpdate);
				equipmentsAttrDao.updateBatchByCondition(params);
			}
		}
		return Collections.emptyList();
	}
	private EquipmentsAttr getCustomTagByHikData(EquipmentsAttr model) {
		switch (model.getCustomTag()) {
			case NETWORK_ADDR:
				model.setCustomTag(CameraModel.IP);
				model.setName(CameraModel.IP_NAME);
				break;
			case NETWORK_PORT:
				model.setCustomTag(CameraModel.PORT);
				model.setName(CameraModel.PORT_NAME);
				break;
			case INDEX_CODE:
				model.setCustomTag(CameraModel.INDEX_CODE);
				model.setName(CameraModel.INDEX_CODE_NAME);
				break;
			case CAMERA_ID:
				model.setCustomTag(CameraModel.CAMERA_ID);
				model.setName(CameraModel.CAMERA_ID_NAME);
				break;
			case DEVICE_ID:
				model.setCustomTag(CameraModel.DEVICE_CODE);
				model.setName(CameraModel.DEVICE_CODE_NAME);
				break;
			case MATRIX_CODE:
				model.setCustomTag(CameraModel.MATRIX_CODE);
				model.setName(CameraModel.MATRIX_CODE_NAME);
				break;
		}
		return model;
	}
}
